#include <fstream>
#include <iostream>		
#include <string>
#include <ctime>

#define maxbook 300           //最大数目数量
#define maxuser 100           //最大用户数量
#define borsum 5			  //最大借书数量

using namespace std;							

int usum,booksum;			  //全局变量,用来存放数目总数和用户总数，程序启动时由usum.txt、booksum.txt分别读入

char r_name[40];             //用户姓名,全局(临时)变量
char i_name[40];             //书籍名字,全局(临时)变量
char i_author[20];           //书籍名字,全局(临时)变量
char i_publisher[40];        //书籍名字,全局(临时)变量

struct User					
{
  char uname[40];            //任可见字符组合
  char usex;
  int uid;                   //数字和字母组合
  int ugrade;               
};

struct Book                  //声明结构体类型Book
{ 
  char bname[40];
  char bauthor[20];
  char bkeyword;			 //关键字查询用是A-Z 以后判断用
  char bpublisher[40];
  long bid;                  //书籍编号
  int lsum;                  //该书借出数量
  int bsum;					 //这本书的总数
  int flag;					 //标志书还在不在书架上，有没有被删除
};

struct Borrow		         //声明结构体类型Borrow
{
  long bid;
  char bname[40];				
  time_t bdate;						
  int flag;					 //标志数组里面这个位置用了没有，是空的值为零。还书的时候这里清零，借书置为1。                                                                                 ！
};					         //Borrow也定义成结构体，Borrow不是借书函数，是Card里面的一个子项

struct Card
{
  int uid;
  char uname[40];
  Borrow bor[5];
  int csum;					//已经借书的本书，添加用户时已经初始化为0
};

//**********添加图书的函数*************//

int Addbook()            
{  
  int server_num(int,int,int);                //用来处理整型数据的输入
  char char_input();                          //用来处理单个字符的输入
  char * all(char *,int t);                   //处理任意可见字符的输入
  void display(Book&p);                       //声明显示书本信息的函数
  
  int i,c,j=-1;
  Book p,list[maxbook];                       //建立一个临时Book类型的对象book      

  fstream iofile;
  ifstream infile;
  ofstream outfile;	

  cout<<"请输入需要添加图书名称：";strcpy(p.bname,all(i_name,40));cout<<endl;        //输入书名
  memset(i_name,0,sizeof(i_name));              //清空数组
  cout<<"请输入图书的五位数编号：";p.bid=server_num(10000,99999,5);                  //输入书的ID号
  cout<<"请输入需要添加图书作者：";strcpy(p.bauthor,all(i_author,20));cout<<endl;    //输入作者
  memset(i_author,0,sizeof(i_author));         //清空数组
  cout<<"请输入添加的图书出版社：";strcpy(p.bpublisher,all(i_publisher,40));cout<<endl;//输入出版单位
  memset(i_publisher,0,sizeof(i_publisher));   //清空数组
  cout<<"请输入图书的关键字 A-Z：";p.bkeyword=char_input();cout<<endl;               //设置关键字
  cout<<"如要添加2本书,请输入02：";p.bsum=server_num(1,99,2);                        //书的数量1-99之间
  cout<<"输入数字1 确认此书信息：";p.flag=server_num(1,1,1);cout<<endl;              //确认输入书的信息
	
  c=booksum;      //数目总数

  if(c==0) 
  {   
    cout<<"你所添加的书目信息如下：\n";cout<<"\n";display(p);
    p.lsum=0;       //该书借出数量的初始化	
		
    iofile.open("book.txt",ios::in|ios::out|ios::binary);     //以输入输出方式打开book.txt
    if(!iofile){cerr<<"打开失败!"<<endl;abort();}
    iofile.seekp(0,ios::beg);
    iofile.write((char*)&p,sizeof(p));
    iofile.close();
    outfile.open("booksum.txt",ios::out);
    booksum=booksum+1;
    outfile<<booksum;
    outfile.close();
  }

  else
  {   
    iofile.open("book.txt",ios::in|ios::out|ios::binary);
    for(i=0;i<c;i++)
    {
	  iofile.seekg(i*sizeof(list[i]),ios::beg);
	  iofile.read((char*)&list[i],sizeof(list[i]));
	  if(p.bid==list[i].bid){j=i;break;}
    }
    iofile.close();
    if(j==-1)
    {   
	  cout<<"你所添加的书目信息如下：\n";cout<<"\n";display(p); 
	  p.lsum=0;       //该书借出数量的初始化
	  
	  iofile.open("book.txt",ios::in|ios::out|ios::binary);
	  iofile.seekp(0,ios::end);
	  iofile.write((char*)&p,sizeof(p));
	  iofile.close();
	  outfile.open("booksum.txt",ios::out);
	  booksum=booksum+1;
	  outfile<<booksum;
	  outfile.close();
    }
    else if(j>=0)
    {  
	  if(list[j].flag==1)
	  {
	    cout<<"数目记录已存在，该书目将添加进原记录"<<endl;
	    list[j].bsum=list[j].bsum+p.bsum;
		p=list[j];
	  }
	  else 
	  {
	    cout<<"数目记录已删除，重新更新该书目的记录"<<endl;
		p.lsum=0;       //该书借出数量的初始化
	  }
	  iofile.open("book.txt",ios::in|ios::out|ios::binary);
	  iofile.seekg(j*sizeof(p),ios::beg);
	  iofile.write((char*)&p,sizeof(p));
	  iofile.close();
    }
    else cerr<<"出现错误"<<endl;
  }
  int temp=8;                             //设置一个临时值用来保存函数的返回值，用以控制函数流程
  cout<<"\n添加完毕,输入数字0返回主菜单：";
  cin>>temp;               
  return temp;
}

//*********删除书籍信息的函数***************//

int Deletebook()
{
  int server_num(int,int,int);                //处理整型数据输入
  void display(Book&);                        //用来显示书本信息
  
  int temp;                                   //设置一个临时值,用来判断是否删除书本
  int i,j=-1;

  ifstream infile;
  fstream iofile;

  Book p,list[maxbook];                          //建立一个临时Book类型的对象book  

  cout<<"请输入要删除的书编号：";p.bid=server_num(10000,99999,5);cout<<endl;

  infile.open("book.txt",ios::in|ios::binary);   //读入书库信息

  for(i=0;i<booksum;i++)
  {
    infile.read((char*)&list[i],sizeof(list[i]));
    if(p.bid==list[i].bid){j=i;break;}
  }
  infile.close();

  if(j==-1){cout<<"书库里没有这本书：";goto loop;}

  else 
  {
    p=list[i];
	if(list[i].flag==0){cout<<"这本书存在,但是现在已经被删除!"<<endl<<endl;goto loop;}
    else 
	{
	  if(list[i].lsum==0)             //未借出,可以删除
	  {
	    cout<<"你要删除的书的信息如下："<<endl<<endl;
	    display(p);
        cout<<"输入1 确认删除该书籍：";temp=server_num(1,1,1);   //输入1删除书籍
        if(temp=1) 
	    {
	      p.flag=0;
		  p.bsum=0;
	      iofile.open("book.txt",ios::in|ios::out|ios::binary);
	      iofile.seekp(j*sizeof(p),ios::beg);
	      iofile.write((char*)&p,sizeof(p));
	      iofile.close();
	      temp=0;
	      cout<<"删除成功！\n"<<endl;
	    }
	    else ;
	  }
	  else cout<<"该书已经借出 "<<list[i].lsum<<" 本,不能删除!"<<endl<<endl;
	}
  }

loop:
  cout<<"输入0 返回到主菜单：";
  cin>>temp;
  return temp;
}

//**********书籍添加和删除的书籍管理函数*************//

int Bookmanagement()
{
  void menu_book();                            //书籍添加删除菜单
  int server_num(int,int,int);                //处理整型数据输入

  int t,temp;
  
  
  menu_book();

  cout<<"\n请输入你需要的服务序号：";
  
  t=server_num(1,2,1);
  
  switch(t)
  {
    case 1:temp=Addbook();break;
	case 2:temp=Deletebook();break;
	default:break;
  }

  return temp;
}

//**********借书函数*************//

int Bookborrow()
{
  User user[maxuser];
  Card card[maxuser];
  Book book[maxbook];

  int server_num(int,int,int);                //用来处理整型数据的输入
  char char_input();                          //用来处理单个字符的输入
  char * char_num(char *,int t);              //定长字符数字组合的输入
  void display(Book&p);                       //显示书本信息
  
  time_t timenow;
  time(&timenow);

  int stuid;
  int bookid;
  int i,j,f=0,k=0;
  int temp=8;                 //设置一个临时值用来保存函数的返回值，用以控制函数流程
  int userno,bookno,cardno;   //分别表示当前的用户号，书号，卡号
  ifstream ruser;
  ifstream rcard;
  ifstream rbook;
  fstream wcard;
  fstream wbook;

  cout<<endl<<"请输入学生编号：";stuid=server_num(20000000,30000000,8);cout<<"\n";    //输入学生的ID

  ruser.open("user.txt",ios::in|ios::binary);	      
  if(!ruser){cout<<"读取user.txt!错误"<<endl;exit(1);}
  ruser.read((char*)&user[0],sizeof(user));
  ruser.close();

  for(i=0;i<usum;i++)
  {
    if(user[i].uid==stuid)	 //若学号输入无误，显示学生信息
    {
      cout<<"用户存在，信息如下：\n"<<endl;
      cout<<"学号："<<user[i].uid<<endl<<endl;
      cout<<"姓名："<<user[i].uname<<endl<<endl;
      cout<<"性别："<<user[i].usex<<endl<<endl;
      cout<<"年级："<<user[i].ugrade<<endl<<endl;
      userno=i;
      f=1;						         //f=1表示用户存在，f=0表示用户不存在
      break;
    }
  }									
  if(f==0){cout<<"用户不存在"<<endl;goto loop;}				//返回主函数	  
  
  rcard.open("card.txt",ios::in|ios::binary);				//然后读入Card.txt，根据CSum是否大于等于5，判断能否借书
  if(!rcard){cout<<"读取card.txt!错误"<<endl;exit(1);}
  rcard.read((char*)&card[0],sizeof(card));
  rcard.close();

  for(i=0;i<usum;i++)
  {
    if(card[i].uid==stuid)
    {
	  cout<<"已经借了"<<card[i].csum<<"本书,";
	  cardno=i;
	  j=borsum-card[i].csum;
	  cout<<"还可以借"<<j<<"本书\n\n"<<endl;
	  break;
    }
  }
  if(j==0){cout<<"不能再借书了！"<<endl;goto loop;}				  //返回主函数 
		
  else
  {
    cout<<"请输入要借阅的书籍编号：";bookid=server_num(10000,99999,5);cout<<"\n";
    
    rbook.open("book.txt",ios::in|ios::binary);	      
    if(!rbook){cout<<"读取book.txt!错误"<<endl;exit(1);}
    rbook.read((char*)&book[0],sizeof(book));
    rbook.close();
	
	for(i=0;i<booksum;i++)if(book[i].bid==bookid){k=1;bookno=i;break;}
	
    if(k==0){cout<<"输入错误,或者该书不存在！"<<endl;goto loop;}					//错误的书籍编号
				 
    else
    {
	  if(book[bookno].flag==0){cout<<"该书已经被删除"<<endl;goto loop;}//正确的书籍编号，标志位为零，已经被删除
	  else										//正确的书籍编号，标志位为一，但是只剩一本书
	  {
	    if(book[bookno].bsum<=1){cout<<"该类图书只剩保存本，不能借阅"<<endl;goto loop;}			
	    else									//终于可以借书了啊…修改①Book[i].bsum；②Card[i].CSum；③Card[i].bor
	    {
		  book[bookno].bsum--;
		  book[bookno].lsum++;
		  card[cardno].csum++;
		  for(i=0;i<borsum;i++)
		  {
		    if(card[cardno].bor[i].flag==0)
			{	
				card[cardno].bor[i].flag=1;
		        card[cardno].bor[i].bid=book[bookno].bid;
		        strcpy(card[cardno].bor[i].bname,book[bookno].bname);  //Card[i].bor[j].bname=Book[i].bname;
				card[cardno].bor[i].bdate=timenow;
			    break;
			}
		  }   
		  cout<<"你借阅书籍的名字："<<book[bookno].bname<<endl;
		  cout<<"你借阅书籍的编号："<<book[bookno].bid<<endl;
		  cout<<"借阅书籍的出版社："<<book[bookno].bpublisher<<endl;
		  cout<<"你借阅书籍的时间："<<ctime(&card[cardno].bor[i].bdate)<<endl;

		  wbook.open("book.txt",ios::in|ios::out|ios::binary);
		  if(!wbook){cerr<<"open error!"<<endl;exit(1);}      //修改书目文件信息
							 
		  wbook.seekp(bookno*sizeof(book[bookno]),ios::beg);
		  wbook.write((char*)&book[bookno],sizeof(book[bookno]));
		  wbook.close();

		  wcard.open("card.txt",ios::in|ios::out|ios::binary);
		  if(!wcard){cerr<<"open error!"<<endl;abort();}     //修改借书证信息
							
		  wcard.seekp(cardno*sizeof(card[cardno]),ios::beg);
		  wcard.write((char*)&card[cardno],sizeof(card[cardno]));
		  wcard.close();
	    }
	  }
    }
  }
  loop:
  cout<<"\n执行完毕,输入数字0返回主菜单：";
  cin>>temp;cin.ignore();                 //清空这次回车
  return temp;
}

//**********还书函数*************//

int Bookreturn()
{  
  ifstream infile;
  ifstream rcard;
  ifstream rbook;
  fstream wcard;
  fstream wbook;
  
  int server_num(int,int,int);                //用来处理整型数据的输入
  char char_input();                          //用来处理单个字符的输入
  char * char_num(char *,int t);              //处理字符数字组合的输入
  
  User user[maxuser];
  Card card;
  Book book[maxbook];
  
  int stuid;
  long bookid;
  int i,j,f=0;                                        //f设置处置0.用来判断用户是否存在
  int temp=0;                                         //设置一临时值用来判断是否有借书记录
  int uno,bno;

  cout<<endl<<"请输入该学生的8位学号：";stuid=server_num(20000000,30000000,8);cout<<endl;     //输入学生的学号
  
  infile.open("user.txt",ios::in|ios::binary);   
  if(!infile){cout<<"读取user.txt失败\n";exit(1);}    //打开user.txt文件  
  infile.read((char*)&user[0],sizeof(user));          //读取user.txt文件
  infile.close();

  for(i=0;i<usum;i++)
  {
    if(user[i].uid==stuid)
	{
	  cout<<"用户存在。";                             //f=1表示用户存在，f=0表示用户不存在 
	  f=1;
	  uno=i;
	  break;
    }
  }
  if(f==0){cout<<"用户不存在"<<endl; goto loop;}      //返回主函数!这样就能返回主函数了啊？
 
  rcard.open("card.txt",ios::in|ios::binary);	     //输入书的信息，如果正确就归还：bsum+1；删除借书条目,Card.CSum，Borrow的信息
  if(!rcard){cout<<"读取card.txt失败\n";exit(1);}
  rcard.seekg(uno*sizeof(card),ios::beg);
  rcard.read((char*)&card,sizeof(card));    	     //将该学生所有借书信息读入内存,直接读入学生卡的信息就可以了？
  rcard.close();

  cout<<"借书记录如下：\n"<<endl<<endl;              //显示还书之前的借书记录
  for(i=0;i<borsum;i++)
  if(card.bor[i].flag==1)                            //显示借书信息
  {
    cout<<"书籍名字："<<card.bor[i].bname<<endl<<endl;
	cout<<"书籍编号："<<card.bor[i].bid<<endl<<endl;
	cout<<"借书时间："<<ctime(&card.bor[i].bdate)<<endl<<endl;

	temp=temp+1;
	cout<<endl;
  }
  else ;

  if(temp==0){cout<<"该用户没有相关借书记录\n\n"; goto loop;}
  
  cout<<"请输入要还书编号：";bookid=server_num(10000,99999,5);cout<<endl;

  for(j=0;j<borsum;j++)
  {	 
    f=0;                                            //f 重置为0
    if(card.bor[j].bid==bookid)
    {
	  if(card.bor[j].flag==1)
	  {
	    card.bor[j].flag=0;							//找到了,修改标志位，表示这本书已经还了,并清除信息										//怎么清除？
	    card.csum--;							        //已借书本数减1
	    f=1;
	    cout<<"操作成功，此书已经归还！\n"<<endl;
	    break;
	  }
	  else {cout<<"你没有借阅此书,或该书已经被删除！"<<endl;goto loop;break;}
    }
  }
  if(f==0){cout<<"您没有借阅这本书!\n"<<endl;}

  cout<<"现在该同学的借书记录:\n"<<endl;            //归还之后的借书记录
  if(card.csum==0)cout<<"借书记录为空\n";
  for(i=0;i<borsum;i++)
  if(card.bor[i].flag==1)
  {
	  cout<<"书记名字："<<card.bor[i].bname<<endl<<endl;	  
	  cout<<"书籍编号："<<card.bor[i].bid<<endl<<endl;
	  cout<<"借书时间："<<ctime(&card.bor[i].bdate)<<endl<<endl;
  }

  wcard.open("card.txt",ios::in|ios::out|ios::binary);		
  if(!wcard){cout<<"读取card.txt失败\n";exit(1);}
  wcard.seekp(uno*sizeof(card),ios::beg);								
  wcard.write((char*)&card,sizeof(card));          //把Card的内容写回文件
  wcard.close();
												   
  rbook.open("book.txt",ios::in|ios::binary);	   //把book.txt内容读入内存
  if(!rbook){cout<<"读取book.txt失败\n";exit(1);}
  rbook.read((char*)&book[0],sizeof(book));
  rbook.close();

  for(i=0;i<booksum;i++)
  if(book[i].bid==bookid)
  {book[i].bsum++;book[i].lsum--;bno=i;break;}	  //找到书了，然后书总数加1;借出的总数量减1
  
  wbook.open("book.txt",ios::in|ios::out|ios::binary);
  if(!wbook){cout<<"读取book.txt失败\n";exit(1);} 
  wbook.seekp(bno*sizeof(book[bno]),ios::beg);									
  wbook.write((char*)&book[bno],sizeof(book[bno]));
  wbook.close();
  
  loop:
  int m=8;                                  //设置一个临时值用来保存函数的返回值，用以控制函数流程
  cout<<"\n执行完毕,输入数字0 返回主菜单：";
  cin>>m;cin.ignore();                     //清空这次回车
  return m;
}

//**********添加用户函数*************//

int Adduser()
{  
  int server_num(int,int,int);                //用来处理整型数据的输入
  char char_input();                          //用来处理单个字符的输入
  char * char_num(char *,int t);              //处理字符数字组合的输入
  char * all(char *,int t);                   //处理任意可见字符的输入,t是他的合法长度的上限
  void u_display(User&p);
  
  int i,c,j=-1;
  User list[maxuser];
  User p;
  Card g;
  
  fstream iofile;
  ifstream infile;
  ofstream outfile;
	
loop:
  cout<<"\n请输入你需要添加的用户姓名：";strcpy(p.uname,all(r_name,40));cout<<endl; 	
  memset(r_name,0,sizeof(r_name));                //清空数组
 
  cout<<"用户编号(8 位数字字母组合)：";p.uid=server_num(20000000,30000000,8); 
  
  cout<<"用户年级(4 位数字例如2009)：";p.ugrade=server_num(2000,3000,4);
  
  do{cout<<"该用户的性别(男：M，女：F)：";p.usex=char_input();cout<<endl;}while((p.usex)!=70&&(p.usex)!=77);  

  c=usum;

  if(c==0) 
  {   
    cout<<"当前已有"<<c<<"位用户"<<endl<<endl;cout<<"你所添加的用户信息为："<<endl<<endl;u_display(p);
		
    iofile.open("user.txt",ios::in|ios::out|ios::binary);         //以输入输出方式打开user.txt文件
	if(!iofile){cout<<"读取user.txt失败\n";exit(1);}

    iofile.seekp(0,ios::beg);
    iofile.write((char*)&p,sizeof(p));
    iofile.close();

    outfile.open("usum.txt",ios::out);
    usum=usum+1;
    outfile<<usum;
    outfile.close();

    iofile.open("card.txt",ios::in|ios::out|ios::binary);
    if(!iofile){cout<<"读取card.txt失败\n";exit(1);}

    g.uid=p.uid;
    strcpy(g.uname,p.uname);
    g.csum=0; 
	for(i=0;i<borsum;i++) g.bor[i].flag=0;
    iofile.seekp(0,ios::beg);                            //这里没有对bor初始化，应该没有问题，不影响存储的字节数
    iofile.write((char*)&g,sizeof(g));
    iofile.close();
  }
  else
  {   
    iofile.open("user.txt",ios::in|ios::out|ios::binary);
	if(!iofile){cout<<"读取card.txt失败\n";exit(1);}
    for(i=0;i<c;i++)
    {
	  iofile.seekg(i*sizeof(list[i]),ios::beg);
	  iofile.read((char*)&list[i],sizeof(list[i]));
	  if(list[i].uid==p.uid){j=i;break;}
    }
    iofile.close();
	
    if(j==-1)
    { 
	  cout<<"当前已有"<<c<<"位用户"<<endl<<endl;cout<<"你所添加的用户信息为："<<endl<<endl;u_display(p);
		
	  iofile.open("user.txt",ios::in|ios::out|ios::binary);
	  iofile.seekp(0,ios::end);
	  iofile.write((char*)&p,sizeof(p));
	  iofile.close();
	  outfile.open("usum.txt",ios::out);
	  usum=usum+1;
	  outfile<<usum;
	  outfile.close();
	  iofile.open("card.txt",ios::in|ios::out|ios::binary);
	  iofile.seekp(0,ios::end);
	  g.uid=p.uid;
	  strcpy(g.uname,p.uname);
	  g.csum=0;                                  //对card 信息里的已经书籍数初始化
	  for(i=0;i<borsum;i++) g.bor[i].flag=0;
	  iofile.write((char*)&g,sizeof(g));
	  iofile.close();
    }
    else if(j>=0){cout<<"你所输入的用户已存在\n"<<endl;}
    else cerr<<"出现错误"<<endl;
  }
  int temp=8;                                   //设置一个临时值用来保存函数的返回值，用以控制函数流程
  cout<<"\n执行完毕,输入数字0返回上层,输入1一返回本层：";
  cin>>temp;cin.ignore();                      //清空这次回车,以便下次用getline()读入主函数服务号
  if(temp==1) goto loop;
  else ;
  return temp;
}

//**********查询图书的函数*************//

int search_book()
{   
  void author_search(char author[]);     //声明按作者名查询的函数
  void keyword_search(char keyword);     //声明按关键字查询的函数
  void bookid_search(long bookid);       //声明按书编号查询的函数
  void display();                        //声明显示查询结果的函数
  void search_console();                 //显示查询系统主界面函数
  void systime();                        //声明显示控制台时间函数
  
  int server_num(int,int,int);           //用来处理整型数据的输入
  char char_input();                     //用来处理单个字符的输入
  char * all(char *,int t);              //处理任意可见字符的输入,t是他的合法长度的上限

  long input_bookid;
  char input_author[20];
  char input_keyword;
  int n;                                //设置一个临时值用来控制查询函数流程
  int temp=8;                           //设置一个临时值用来保存函数的返回值,用以控制函数流程
  
loop:
  systime();
  search_console();
  cout<<"\n请输入你需要的服务序号：";
  n=server_num(0,3,1);                  //域的下限是0,上限是3,1是长度
  switch(n)								//选定查询方式,1、2、3 分别代表书名、作者、关键字查询
  {
    case 1:cout<<"请输入查询图书的序列号：";input_bookid=server_num(10000,99999,5);cout<<"\n";bookid_search(input_bookid);break;		 //按书籍的编号查询
	case 2:cout<<"请输入查询图书的作者名：";strcpy(input_author,all(i_author,20));cout<<"\n";author_search(input_author);break;      //按书籍的作者查询
	case 3:cout<<"请输入查询图书的关键字：";input_keyword=char_input();cout<<"\n";keyword_search(input_keyword);break;   //按书籍关键字查询
    default:temp=n;break;
  }
  
  if(n==1||n==2||n==3) {cout<<"\n查询完毕,输入数字0返回上层,输入1一返回本层：";cin>>temp;cin.ignore();}//清空这次回车
  if(temp==1) goto loop;
  else ;
  return temp;
}

// ********* 主函数 *********  //

int main()
{
  void console();                    //声明控制台界面函数
  void systime();                    //声明控制台时间函数
  void cfile();                      //第一次创建文件函数
  int read_booksum();                //读取书目数量的函数
  int read_usum();                   //读取用户数量的函数
  int server_num(int,int,int);       //声明服务号输入函数
  int t;                             //声明系统的服务序号

  system("title 图书管理系统");
  cfile();
  booksum=read_booksum();            //读取目前的书目总数
  usum=read_usum();                  //读取目前的用户总数
  
loop:systime();
  cout<<endl;
  console(); 
  cout<<endl;
  cout<<"请输入你需要的服务序号：";
  t=server_num(0,5,1);                //域的下限为0,上限为5
  int temp=8;                         //设置一个临时值来保存子函数的返回值，用来控制主函数的流程
  switch(t)
  {
    case 1:temp=Bookmanagement();cin.ignore();break;
    case 2:temp=Bookborrow();break;
    case 3:temp=Bookreturn();break;
    case 5:temp=Adduser();break;
    case 0:exit(1);
    default:temp=search_book();break;
  }
  if(temp==0) goto loop;
  else ;
  return 0;
}

// ********* 控制台界面 *********  //

void console()
{
  cout<<"\t\t\t※※※※※※※※※※※※※※※※※\n";
  cout<<"\t\t\t※                              ※\n";
  cout<<"\t\t\t※****图**书**管**理**系**统****※\n";
  cout<<"\t\t\t※                              ※\n"; 
  cout<<"\t\t\t※       1: 书 籍 添 删         ※\n";
  cout<<"\t\t\t※                              ※\n"; 
  cout<<"\t\t\t※       2: 借 阅 书 籍         ※\n";
  cout<<"\t\t\t※                              ※\n"; 
  cout<<"\t\t\t※       3: 归 还 书 籍         ※\n";
  cout<<"\t\t\t※                              ※\n"; 
  cout<<"\t\t\t※       4: 查 询 书 籍         ※\n";
  cout<<"\t\t\t※                              ※\n"; 
  cout<<"\t\t\t※       5: 添 加 用 户         ※\n";
  cout<<"\t\t\t※                              ※\n";  
  cout<<"\t\t\t※       0: 退 出 系 统         ※\n";
  cout<<"\t\t\t※                              ※\n";
  cout<<"\t\t\t※※※※※※※※※※※※※※※※※\n";
}

// ********* 控制台时间 *********  //

void systime()
{
  cout<<endl;
  cout<<"\t\t\t    当前日期：";system("DATE  [/T]");
  cout<<endl;
  cout<<"\t\t\t    当前时间：";system("TIME  [/T]");
  cout<<endl;	
}

// ********* 整型数值输入和判断域的函数 *********  //

int server_num(int r,int s,int z)             //r为域的下限,s为域的上限,z为长度
{
  int int_input(int);                         //输入字符串纠错函数，转化为int 型
  int a,t;
  
  a=int_input(z);
  cout<<endl;
  if(a<r||a>s)                                //输入的服务序号不在预定义范围内，递归调用输入函数
  {
    cout<<"值不在域内,请输入值在"<<r<<"-"<<s<<"之间,长度为"<<z<<" 的数：";
    t=server_num(r,s,z);
  } 
  else t=a;
  return t;
}

// ********* 显示书籍信息函数 *********  //

void display(Book&p)                                                        //查询结果显示函数
{
  cout<<"\n书编号："<<p.bid<<"\n"<<endl;
  cout<<"书  名："<<p.bname<<"\n"<<endl;
  cout<<"关键字："<<p.bkeyword<<"\n"<<endl;
  cout<<"作  者："<<p.bauthor<<"\n"<<endl;
  cout<<"出版商："<<p.bpublisher<<"\n"<<endl;
  cout<<"数  量："<<p.bsum<<"本"<<"\n"<<endl;
}


// ********* 显示用户信息函数 *********  //

void u_display(User&p)                                                        //查询结果显示函数
{
  cout<<"用户名："<<p.uname<<"\n"<<endl;
  cout<<"学  号："<<p.uid<<"\n"<<endl;
  cout<<"性  别："<<p.usex<<"\n"<<endl;
  cout<<"年  级："<<p.ugrade<<"\n"<<endl;
}

// ********* 按作者名的查询函数 *********  //

void author_search(char author[])                                         //按图书作者名的查询函数
{
  int i;
  Book book[maxbook];
  ifstream infile("book.txt",ios::binary);                                //定义输入文件流，以输入方式打开磁盘文件！
  if(!infile){cerr<<"open Book.txt error!"<<endl;exit(1);}
  infile.read((char*)&book[0],sizeof(book));
  infile.close();
  int temp=0;
  for(i=0;i<maxbook;i++)
  if(strcmp(book[i].bauthor,author)==0)					
  {
	 if(book[i].flag==1)display(book[i]);else {cout<<"该书已被删除！"<<endl;display(book[i]);}
	 ++temp;
  }
  if(temp==0) 
	  cout<<"查无此书！\n"<<endl;
  else ;
}

// ********* 按关键字的查询函数 *********  //

void keyword_search(char keyword)                                       //按图书关键字的查询函数
{
  int i;
  Book book[maxbook];
  ifstream infile("book.txt",ios::binary);                              //定义输入文件流，以输入方式打开磁盘文件！
  if(!infile){cerr<<"open Book.txt error!"<<endl;exit(1);}
  infile.read((char*)&book[0],sizeof(book));
  infile.close();
  int temp=0;
  for(i=0;i<maxbook;i++)
  if(book[i].bkeyword==keyword)					
  {	 
	 if(book[i].flag==1)display(book[i]);else {cout<<"该书已被删除！"<<endl;display(book[i]);}
	 ++temp;
  }
  if(temp==0) 
	  cout<<"查无此书！\n"<<endl;
  else ;
}

// ********* 按书编号的查询函数 *********  //

void bookid_search(long bookid)                                       //按图书序列号的查询函数
{
  int i;
  Book book[maxbook];
  ifstream infile("book.txt",ios::binary);                            //定义输入文件流，以输入方式打开磁盘文件！
  if(!infile){cerr<<"open book.txt error!"<<endl;exit(1);}
  infile.read((char*)&book[0],sizeof(book));
  infile.close();
  int temp=0;
  for(i=0;i<maxbook;i++)
  if(book[i].bid==bookid)					
  {
	 if(book[i].flag==1)display(book[i]);else {cout<<"该书已被删除！"<<endl;display(book[i]);}
	 ++temp;
  } 
  if(temp==0) 
	  cout<<"查无此书！\n"<<endl;
  else ;
}

// ********* 查询函数的主界面 *********  //

void search_console()
{
  cout<<"\t\t\t※※※※※※※※※※※※※※※※※\n";
  cout<<"\t\t\t※                              ※\n";
  cout<<"\t\t\t※****图**书**查**询**系**统****※\n";
  cout<<"\t\t\t※                              ※\n"; 
  cout<<"\t\t\t※       1: 按 书 编 号         ※\n";
  cout<<"\t\t\t※                              ※\n"; 
  cout<<"\t\t\t※       2: 按 作 者 名         ※\n";
  cout<<"\t\t\t※                              ※\n"; 
  cout<<"\t\t\t※       3: 按 关 键 字         ※\n";
  cout<<"\t\t\t※                              ※\n"; 
  cout<<"\t\t\t※       0: 返 回 上 层         ※\n";
  cout<<"\t\t\t※                              ※\n";
  cout<<"\t\t\t※※※※※※※※※※※※※※※※※\n";
}

// ********* 书籍管理的界面 *********  //

void menu_book()
{
  cout<<"\t\t\t※※※※※※※※※※※※※※※※※\n";
  cout<<"\t\t\t※                              ※\n";
  cout<<"\t\t\t※****书**籍**管**理**系**统****※\n";
  cout<<"\t\t\t※                              ※\n"; 
  cout<<"\t\t\t※       1: 添 加 书 籍         ※\n";
  cout<<"\t\t\t※                              ※\n"; 
  cout<<"\t\t\t※       2: 删 除 书 籍         ※\n";
  cout<<"\t\t\t※                              ※\n";
  cout<<"\t\t\t※※※※※※※※※※※※※※※※※\n";
}


// ********* 读取数目函数,用于管理书籍和定位 *********  //

int read_booksum()
{
  ifstream infile("booksum.txt",ios::in|ios::binary);
  if(!infile){cout<<"读取usum.txt失败\n";exit(1);;}
  infile>>booksum;
  infile.close();
  return booksum;
}

// ********* 读取用户函数,用于管理用户和定位 *********  //

int read_usum()
{
  ifstream infile("usum.txt",ios::in|ios::binary);
  if(!infile){cout<<"读取usum.txt失败\n";exit(1);}
  infile>>usum;
  infile.close();
  return usum;
}

// ********* 创建文件函数,用以第一次运行程序创建文件 *********  //

void cfile()
{
ofstream c_usum;
ofstream c_booksum;
ofstream c_card;
ofstream c_user;
ofstream c_book;
ifstream f_booksum;

f_booksum.open("booksum.txt",ios::in|ios::binary);
if(!f_booksum)
{
cout<<"\n这是你第一次运行程序，程序将在当前目录创建以下文件用以存储数据：\n\n";
cout<<"book.txt     用来存储书库书目信息"<<endl<<endl;
cout<<"user.txt     用来存储用户相关信息"<<endl<<endl;
cout<<"card.txt     用来存储用户借书信息"<<endl<<endl;
cout<<"booksum.txt  用来存储书库书目总数"<<endl<<endl;
cout<<"usumsum.txt  用来存储相关用户总数"<<endl<<endl;

c_usum.open("usum.txt",ios::out|ios::binary);cout<<"创建成功！"<<endl<<endl;
c_booksum.open("booksum.txt",ios::out|ios::binary);cout<<"创建成功！"<<endl<<endl;
c_book.open("book.txt",ios::out|ios::binary);cout<<"创建成功！"<<endl<<endl;
c_card.open("card.txt",ios::out|ios::binary);cout<<"创建成功！"<<endl<<endl;
c_user.open("user.txt",ios::out|ios::binary);cout<<"创建成功！"<<endl<<endl;

cout<<"请妥善保存好以上文件以保证程序正常运行,按任意键继续...";system("pause>nul");cout<<endl<<endl;

c_usum.close();
c_booksum.close();
c_book.close();
c_card.close();
c_user.close();
}
f_booksum.close();

usum=0;
booksum=0;

}

//******字符串处理为数字串(int型)的函数,t为int 型位数******//
 
int int_input(int t)        //例如输入任意字符串,需要返回一个5位数的int值,调用方法为input_sum(5)    
{
	
  int pow(int);             //声明要调用的幂函数
  int i;	
  string str;

loop:
  getline(cin,str);
  if(str.length()>100)
  {
    cout<<"\n输入的字符长度太大,请重新输入：";
    goto loop;
  }
  else ;
  for(i=1;i<str.length();i++)
  {
    if(str[i]<0)
	{cout<<"\n不要输入中文,请重新输入：";goto loop;}
    
	else if((str[i]>0&&str[i]<32)||(str[i]>32&&str[i]<48)||str[i]>57)
	{cout<<"\n请输入"<<t<<" 位"<<"0-9的数字组合：";goto loop;}
    
	else if(str[i]==32)
    {cout<<"\n不要输入空格,请输入"<<t<<" 位"<<"0-9的数字组合：";goto loop;}
	
	else ;
  }
	
  if(str.length()!=t)
  {cout<<"\n字段长度不对,"<<"请输入"<<t<<" 位"<<"0-9的数字组合："; goto loop;}

  else ;

  int temp=0;
  for(i=0;i<t;i++){temp=temp+(str[i]-48)*pow(t-i-1);}         //ASCII码值转化为整型数值

  //cout<<"字符串长度为："<<str.length()<<endl<<endl;         //测试时用到

  return temp;      //函数返回int 型的值
}

 //******以10为底的幂函数100=10*10,t=2 把字符串处理为数字串(int)时用到******//    
 
int pow(int t)                
{
	int i,temp=1;
	for(i=0;i<=t-1;i++){temp=10*temp;}
	return temp;
}

 //*******处理任意长度的数字和字符串函数,但未使用*****************//
         
char * char_num(char * ch,int t)                   //t为需要返回的"合法"字符串长度
{	
   string str;
loop:
  getline(cin,str);
  if(str.length()>100)                  //判断字符串长度,过滤掉太长的字符串输入
  {cout<<"\n输入的字符长度太大,请重新输入：";goto loop;}

  for(int i=0;i<str.length();i++)
  {
    if(str[i]<0)                        //过滤中文等多字节编码文字
	{cout<<"\n不要输入中文,请重新输入：";goto loop;}
    
	else if(str[i]==32)
    {cout<<"\n不要输入空格,请输入"<<t<<" 位字母和(或)数字组合：";goto loop;}

	else if(str[i]<48||(str[i]>57&&str[i]<65)||(str[i]>90&&str[i]<97)||str[i]>122) //过滤非字母和数字组合的字符串
	{cout<<"\n请输入长度为"<<t<<" 位的字母和(或)数字组合：";goto loop;}
    
	else ;	
  }	
  if(str.length()!=t)                 //判断标准的可见的ASCII码字符串长度，用来处理要求定长的输入
  {cout<<"\n字段长度不对,"<<"请输入"<<t<<" 位"<<"字母和(或)数字组合："; goto loop;}

  else ;

  for(i=0;i<t;i++) ch[i]=str[i];
  
  //*测试用*/cout<<"str长度为："<<str.length()<<"  ch数组的长度为："<<sizeof(ch)<<endl;   //str的长度为t,a仍为100，但在赋给相应的变量的时只取t位
  
  return ch;
}

 //**************处理任意长度的可见字符的输入,包括中文等*****************//
         
char * all(char * ch,int t)                      //t为需要返回的"合法"字符串长度
{
  string str;
loop:
  getline(cin,str);
  if(str.length()>t)                  //判断字符串长度,过滤掉太长的字符串输入
  {cout<<"\n输入的字符长度太大,请重新输入：";goto loop;}
  
  else ;
  
  for(int i=0;str[i]!='\0';i++) ch[i]=str[i];  
  
  return ch;
}

 //**************处理单个字符A-Z输入的函数*****************//
         
char char_input()               
{	
  string str;
loop:
  getline(cin,str);
  if(str.length()>100)                  //判断字符串长度,过滤掉太长的字符串输入
  {cout<<"\n输入的字符长度太大,请重新输入：";goto loop;}

  for(int i=0;i<str.length();i++)
  {
    if(str[i]<0)                        //过滤中文等多字节编码文字
	{cout<<"\n不要输入中文,请重新输入：";goto loop;}
    
	else if(str[i]==32)
    {cout<<"\n不要输入空格,请输入A-Z中的某一个字符：";goto loop;}

	else if(str[i]<65||str[i]>90){cout<<"\n非法字符,请输入A-Z中的某一个字符：";goto loop;} //过滤非字母和数字组合的字符串
    
	else ;	
  }
	
  if(str.length()!=1)                 //判断标准的可见的ASCII码字符串长度，用来处理要求定长的输入
  {cout<<"\n字段长度不对,请输入A-Z中的某一个字符："; goto loop;}

  else ; 
  
  char a;

  for(i=0;str[i]!='\0';i++)a=str[i];

  return a;
}

/****************** end of file ******************/

